﻿using System;
using Didaku.Attributes;
using Didaku.Collections;
using Didaku.QEngine.Common.Entities;
using Didaku.QEngine.Common.Interfaces;
using Didaku.QEngine.Common.Interfaces.Entities;
using Didaku.QEngine.Common.Wrapper.Engine;

namespace Didaku.QEngine.Common.Abstracts.Entities
{
    /// <summary>
    ///     描述一个机构：可以理解为银行网点，保险行业、电信、移动行业的营业厅等。
    /// </summary>
    [Serializable]
    public abstract class DepartmentInfo : IDepartment, IDepositories
    {
        #region IDepartment

        [EntityColumn]
        public string Id { get; set; }

        /// <summary>
        ///     网点编号:一般指行业中为该网点定义的编号
        /// </summary>
        [EntityColumn]
        public string Number { get; set; }

        /// <summary>
        ///     网点名称
        /// </summary>
        [EntityColumn]
        public string Name { get; set; }

        /// <summary>
        ///     地区编码
        /// </summary>
        [EntityColumn]
        public string AreaCode { get; set; }

        /// <summary>
        ///     网点的其他相关属性信息集合
        /// </summary>
        [EntityColumn]
        public SerializableMap<string, string> Details { get; set; }

        #endregion

        #region Implementation of IDepositories

        /// <summary>
        ///     当前网点的分区字典。
        /// </summary>
        public abstract SerializableMap<string, District> DistrictMap { get; set; }

        /// <summary>
        ///     当前网点的柜台字典。
        /// </summary>
        public abstract SerializableMap<string, Counter> CounterMap { get; set; }

        /// <summary>
        ///     当前网点的业务类型字典。
        /// </summary>
        public abstract SerializableMap<string, BusinessType> BusinessTypeMap { get; set; }

        /// <summary>
        ///     当前网点的员工字典。
        /// </summary>
        public abstract SerializableMap<string, Staff> StaffMap { get; set; }

        /// <summary>
        ///     当前网点的工作流字典。
        /// </summary>
        public abstract SerializableMap<string, Workflow> WorkflowMap { get; set; }

        /// <summary>
        ///     当前网点的卡片类别字典。
        /// </summary>
        public abstract SerializableMap<string, CardCategory> CardCategoryMap { get; set; }

        /// <summary>
        /// 当前网点的服务队列字典。Key是队列的Id。
        /// </summary>
        public abstract SerializableMap<string, ServiceQueue> ServiceQueueMap { get; set; }

        /// <summary>
        /// 当前网点的服务逻辑字典。Key是柜台的Id，Value指的是服务逻辑。
        /// </summary>
        public abstract SerializableMap<string, ServiceLogic> ServiceLogicMap { get; set; }

        #endregion

        #region IDepartment Members

        public int CompareTo(object obj)
        {
            if (obj == null || !(obj is DepartmentInfo))
                return -1;
            return Number.Equals(((DepartmentInfo) obj).Number) ? 0 : -1;
        }

        public bool Equals(IDepartment other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other.Id, Id) && other.Number == Number;
        }

        #endregion

        public override string ToString()
        {
            return Number;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (DepartmentInfo)) return false;
            return Equals((DepartmentInfo) obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int result = (!Id.Equals(Guid.Empty) ? Id.GetHashCode() : 0);
                result = (result*397) ^ (Number != null ? Name.GetHashCode() : 0);
                result = (result*397) ^ (Name != null ? Name.GetHashCode() : 0);
                return result;
            }
        }

        public static bool operator ==(DepartmentInfo left, DepartmentInfo right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(DepartmentInfo left, DepartmentInfo right)
        {
            return !Equals(left, right);
        }
    }
}